package com.ncloud.aaaa.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ncloud.aaaa.base.Constant;
import com.ncloud.aaaa.model.User;
import com.ncloud.aaaa.model.UserRole;
import com.ncloud.aaaa.model.UserRolePK;
import com.ncloud.aaaa.repository.UserRepository;
import com.ncloud.aaaa.repository.UserRoleRepository;
import com.ncloud.aaaa.util.EncryptUtils;
import com.ncloud.auth.config.RedisItem;
import com.ncloud.auth.config.RedisKeys;
import com.ncloud.auth.service.LocalTokenService;
import com.ncloud.chnl.service.CustAreaUserService;
import com.ncloud.chnl.service.CustUserService;
import com.ncloud.chnl.service.SaleService;
import com.ncloud.common.enmus.ResultEnum;
import com.ncloud.common.exception.UserException;
import com.ncloud.param.service.CommparaService;

@Service
public class UserBusiServiceImpl{
	
	private static final Logger logger = LogManager.getLogger(UserBusiServiceImpl.class);
	@Autowired
	private UserRepository repository;
	@Autowired
	private UserRoleRepository roleRepository;
	@Reference
	private CommparaService paraService;
	@Reference(timeout=3000)
	private SaleService saleService;
	@Reference
	private CustUserService custUserservice;
	@Reference
	private CustAreaUserService areaUserService;
	@Autowired
	private RoleBusiServiceImpl roleBusi;
	@Autowired
	private LocalTokenService tokenService;

	@Transactional
	public JSONObject addUser(JSONObject obj) {
		User user = JSON.parseObject(obj.toJSONString(),User.class);
		User result = saveUser(user);
		JSONObject json = getParamByUserType(user.getUserType());
		obj.put("roleId", json.get("paraCode2"));
		obj.put("jobTitle", json.get("paraCode3"));
		//获取userType对应的角色信息
		saveUserRole(obj,result);
		
		//创建关系
		createUserRel(obj,result);
		
		return JSON.parseObject(JSON.toJSONString(result));
	}
	
	private void createUserRel(JSONObject obj, User user) {
		// 根据userType判断创建和谁的关系 1-系统管理员 2-渠道 3-客户
		JSONObject json = new JSONObject();
		json.put("userID", obj.get("userID"));
		json.put("userId", user.getId());
		json.put("remark",obj.get("remark"));
		String jobTitle = obj.containsKey("jobTitle")?obj.getString("jobTitle"):getJobTitle(user.getUserType());
		if("1".equals(user.getUserType()) || "2".equals(user.getUserType()) || "4".equals(user.getUserType()) || "5".equals(user.getUserType())){
			json.put("chnlId", obj.get("chnlId"));
			json.put("jobTitle", jobTitle);
			saleService.insertSale(json);
		}else if ("3".equals(user.getUserType()) || "6".equals(user.getUserType())) {
			json.put("custId", obj.get("custId"));
			json.put("isManager", jobTitle);
			logger.info("userRel="+json.toJSONString());
			custUserservice.createCustUserRel(json);
			if(obj.containsKey("areaId") && obj.getLong("areaId")!=null){
				json.put("areaId", obj.getLong("areaId"));
				areaUserService.createCustAreaUserRel(json);
			}
		}else {
			throw new UserException(user.getUserType()+"用户类型不存在");
		}
		
	}

	private void saveUserRole(JSONObject obj, User user) {
		Long roleId = null;
		String userType = obj.getString("userType");
		if(obj.containsKey("roleId")){
			roleId = obj.getLong("roleId");
		}else{
			roleId = getRoleId(userType);
		}
		UserRole userRole = new UserRole();
		UserRolePK id = new UserRolePK();
		id.setRoleId(roleId);
		id.setUserId(user.getId());
		userRole.setId(id);
		roleRepository.save(userRole);
		//获取角色关联
		if(obj.containsKey("chnlId")){
			Long chnlId = obj.getLong("chnlId");
			JSONArray relRoles = getRelRoleByChnlId(chnlId);
			for (int i = 0; i < relRoles.size(); i++) {
				JSONObject relRole = relRoles.getJSONObject(i);
				UserRole relUserRole = new UserRole();
				UserRolePK relId = new UserRolePK();
				relId.setRoleId(relRole.getLong("paraCode2"));
				relId.setUserId(user.getId());
				relUserRole.setId(relId);
				roleRepository.save(relUserRole);
			}
		}
	}

	private JSONArray getRelRoleByChnlId(Long chnlId) {
		JSONObject params = new JSONObject();
		params.put("subsysCode", "4a");
		params.put("paramAttr", 1001);
		params.put("paramCode", "CHNL_REL_ROLES");
		params.put("paraCode1", chnlId);
		JSONArray array = paraService.getBsCommparaSvcInfo(params);

		if (array != null && !array.isEmpty() && array.size() > 0) {
			return array;
		}
		return new JSONArray();
	}

	private User saveUser(User user) {
		user.setCreateTime(new Date());
		user.setState(Constant.NORMAL_STATE);
		user.setErrTimes(0);
		user.setUpdateTime(new Date());
		if(user.getPwd()==null){
			user.setPwd(user.getAccount()+Constant.USER_PWD_SUFFIX);
		}
		user.setPwd(EncryptUtils.encryptSHA(user.getPwd()));
		User result = repository.save(user);
		return result;
	}
	
	private Long getRoleId(String userType) {
		JSONObject json = getParamByUserType(userType);
		Long roleId = Long.parseLong(json.getString("paraCode2"));
		return roleId;
	}
	
	private String getJobTitle(String userType) {
		JSONObject json = getParamByUserType(userType);
		String jobTitle = json.getString("paraCode3");
		return jobTitle;
	}
	
	private JSONObject getParamByUserType(String userType) {
		JSONObject json = new JSONObject();
		JSONObject params = new JSONObject();
		params.put("subsysCode", "4a");
		params.put("paramAttr", 1000);
		params.put("paramCode", "USER_TYPE_2_ROLE_JOB");
		params.put("paraCode1", userType);
		JSONArray array = paraService.getBsCommparaSvcInfo(params);

		if (array != null && !array.isEmpty() && array.size() > 0) {
			json = array.getJSONObject(0);
		} else {
			throw new UserException("9999", "USER_TYPE_ROLE_ID参数配置错误");
		}
		return json;
	}

	@Transactional
	public void updateUserInfo(JSONObject json) {
		Long userId = json.getLong("userId");
		User user = repository.findOne(userId);
		String oldUserType = user.getUserType();
		try {
			// 更新用户信息
			updateUser(json,user);
			// 处理分组变更
			if("1".equals(oldUserType) || "2".equals(oldUserType)||"4".equals(oldUserType) || "5".equals(oldUserType)){
				// 更新sale表关系
				updateSale(json);
			}
			if(json.containsKey("oldAreaId")){
				updateCustAreaUser(json);
			}
			// 处理权限变更
			String userType = json.getString("userType");
			if(!oldUserType.equals(userType)){
				//处理角色关系 userRole
				dealUserRole(json,user);
			}
		} catch (Exception e) {
			throw new UserException(ResultEnum.DATABASE_ERROR);
		}
	}

	private void updateCustAreaUser(JSONObject json) {
		JSONObject custAreaUser = areaUserService.getCustAreaUserRelByUserId(json.getLong("userId"));
		if(custAreaUser!=null && !custAreaUser.isEmpty()){
			areaUserService.deleteCustAreaUserRel(custAreaUser);
		}
		if(json.containsKey("areaId") && StringUtils.isNotBlank(json.getString("areaId"))){
			if(json.containsKey("userType")){
				String jobTitle = json.containsKey("jobTitle")?json.getString("jobTitle"):getJobTitle(json.getString("userType"));
				custAreaUser.put("isManager", jobTitle);
			}
			custAreaUser.putAll(json);
			areaUserService.createCustAreaUserRel(custAreaUser);
		}
	}

	private void dealUserRole(JSONObject json, User user) {
		roleBusi.deleteUserRole(json);
		saveUserRole(json,user);
	}

	private void updateSale(JSONObject json) {
		Long userId = json.getLong("userId");
		JSONObject saleParam = new JSONObject();
		saleParam.put("userID", userId);
		JSONObject sale = saleService.getSale(saleParam);
		String jobTitle = json.containsKey("jobTitle")?json.getString("jobTitle"):getJobTitle(json.getString("userType"));
		if(sale.getLong("chnlId")!=json.getLong("chnlId") || !jobTitle.equals(sale.getString("jobTitle"))){
			sale.put("chnlId", json.get("chnlId"));
			if(json.containsKey("userType")){
				sale.put("jobTitle", jobTitle);
			}
			saleService.updateSale(sale);
		}
	}

	private void updateUser(JSONObject json, User user) {
		Long userId = json.getLong("userId");
		
		try {
			if(user==null){
				throw new UserException("userId="+userId+"的用户不存在！");
			}
			if(json.containsKey("name")){
				user.setName(json.getString("name"));
			}
			if(json.containsKey("userType")){
				user.setUserType(json.getString("userType"));
			}
			if(json.containsKey("email")) {
				user.setEmail(json.getString("email"));
			}
			if(json.containsKey("mobile")){
				user.setMobile(json.getString("mobile"));
			}
			if(json.containsKey("telephone")){
				user.setTelephone(json.getString("telephone"));
			}
			if(json.containsKey("remark")){
				user.setRemark(json.getString("remark"));
			}
			user.setUpdateTime(new Date());
			
			repository.save(user);
			updateUserRedis(user);
		} catch (Exception e) {
			throw new UserException(ResultEnum.DATABASE_ERROR);
		}
		
	}
	
	public void updateUserRedis(User user) {
		List<RedisItem> list = new ArrayList<RedisItem>();
		RedisItem item = new RedisItem(RedisKeys.REDIS_USER_LOGIN_PREFIX+user.getAccount(), user, RedisKeys.REDIS_USER_LOGIN_EXPIRE);
		byte[] b = tokenService.get(item);
		if(StringUtils.isNoneBlank(new String(b))){
			list.add(item);
			tokenService.set(list);
		}
	}
	
}
